<template>
  <div class="news-management">
    <h1>咨询与公告管理系统</h1>
    
    <!-- 状态消息 -->
    <div v-if="statusMessage" :class="['status-message', messageType]">
      {{ statusMessage }}
    </div>
    
    <!-- 搜索和筛选区域 -->
    <div class="card">
      <h2>公告列表</h2>
      <div class="search-bar">
        <input type="text" placeholder="搜索关键词" v-model="searchParams.search">
        <input type="number" placeholder="分类ID" v-model.number="searchParams.category_id">
        <select v-model="searchParams.is_top">
          <option value="">全部</option>
          <option value="true">置顶</option>
          <option value="false">非置顶</option>
        </select>
        <button @click="searchNews">搜索</button>
        <button @click="resetSearch">重置</button>
        <button class="btn-primary" @click="showCreateModal">创建公告</button>
      </div>
      
      <!-- 加载状态 -->
      <div v-if="isLoading" class="loading">
        加载中...
      </div>
      
      <!-- 新闻列表 -->
      <div v-else class="news-list">
        <div v-if="newsList.length === 0" style="text-align: center; padding: 30px; color: #7f8c8d;">
          暂无公告数据
        </div>
        
        <div class="news-item" v-for="news in newsList" :key="news.id" @click="viewNewsDetail(news)">
          <div class="news-title">
            <span class="top-tag" v-if="news.is_top">置顶</span>
            {{ news.title }}
          </div>
          <div class="news-abstract">{{ news.abstract }}</div>
          <div class="news-content" v-if="news.cover_image">
            <img :src="news.cover_image" alt="封面" style="max-width: 100%; height: auto;">
          </div>
          <div class="tags" v-if="news.tags && news.tags.length">
            <span class="tag" v-for="(tag, index) in news.tags" :key="index">{{ tag }}</span>
          </div>
          <div class="news-meta">
            <span>分类: {{ news.category_name || news.category_id }}</span>
            <span>{{ formatDate(news.created_at) }}</span>
          </div>
          <div style="margin-top: 15px; display: flex; gap: 10px;">
            <button @click.stop="editNews(news)">编辑</button>
            <button class="btn-danger" @click.stop="deleteNews(news.id)">删除</button>
          </div>
        </div>
      </div>
      
      <!-- 分页 -->
      <div class="pagination" v-if="totalPages > 1">
        <button @click="changePage(1)" :disabled="currentPage === 1">首页</button>
        <button @click="changePage(currentPage - 1)" :disabled="currentPage === 1">上一页</button>
        <span>第 {{ currentPage }} 页，共 {{ totalPages }} 页 (共 {{ totalItems }} 条)</span>
        <button @click="changePage(currentPage + 1)" :disabled="currentPage === totalPages">下一页</button>
        <button @click="changePage(totalPages)" :disabled="currentPage === totalPages">末页</button>
        <div class="page-jump">
          <input type="number" v-model.number="jumpPage" min="1" :max="totalPages" placeholder="页码">
          <button @click="jumpToPage">跳转</button>
        </div>
      </div>
    </div>
    
    <!-- 创建/编辑新闻模态框 -->
    <div class="modal-overlay" v-if="showModal && !showDetailModal" @click="closeModal">
      <div class="modal-container" @click.stop>
        <div class="modal-content">
          <div class="modal-header">
            <h2>{{ editingNews.id ? '编辑公告' : '创建新公告' }}</h2>
            <span class="close" @click="closeModal">&times;</span>
          </div>
          <div class="modal-body">
            <form @submit.prevent="saveNews">
              <div class="form-group">
                <label for="title">标题:</label>
                <input type="text" id="title" v-model="newsForm.title" required>
              </div>
              
              <div class="form-group">
                <label for="cover_image">封面图片:</label>
                <input type="file" id="cover_image" @change="handleImageUpload" accept="image/*">
                <div v-if="newsForm.cover_image" class="image-preview">
                  <img :src="newsForm.cover_image" alt="预览">
                </div>
              </div>
              
              <div class="form-group">
                <label for="abstract">摘要:</label>
                <textarea id="abstract" v-model="newsForm.abstract" rows="3" required></textarea>
              </div>
              
              <div class="form-group">
                <label for="content">内容:</label>
                <textarea id="content" v-model="newsForm.content" rows="6" required></textarea>
              </div>
              
              <div class="form-group">
                <label for="category_id">分类ID:</label>
                <input type="number" id="category_id" v-model.number="newsForm.category_id" required>
              </div>
              
              <div class="form-group">
                <label for="tags">标签 (逗号分隔):</label>
                <input type="text" id="tags" v-model="tagsInput" placeholder="例如: 新闻,公告,活动">
              </div>
              
              <div class="form-group">
                <label>
                  <input type="checkbox" v-model="newsForm.is_top"> 置顶
                </label>
              </div>
              
              <div class="modal-footer">
                <button type="submit">{{ editingNews.id ? '更新公告' : '创建公告' }}</button>
                <button type="button" @click="closeModal">取消</button>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 新闻详情模态框 -->
    <div class="modal-overlay" v-if="showDetailModal" @click="closeDetailModal">
      <div class="modal-container" @click.stop>
        <div class="modal-content">
          <div class="modal-header">
            <h2>公告详情</h2>
            <span class="close" @click="closeDetailModal">&times;</span>
          </div>
          <div class="modal-body">
            <div class="news-detail">
              <h3>{{ detailNews.title }}</h3>
              <div class="news-meta">
                <span>分类: {{ detailNews.category_name || detailNews.category_id }}</span>
                <span>{{ formatDate(detailNews.created_at) }}</span>
                <span v-if="detailNews.is_top" class="top-tag">置顶</span>
              </div>
              <div class="news-cover" v-if="detailNews.cover_image">
                <img :src="detailNews.cover_image" alt="封面">
              </div>
              <div class="news-content">
                {{ detailNews.content }}
              </div>
              <div class="tags" v-if="detailNews.tags && detailNews.tags.length">
                <span class="tag" v-for="(tag, index) in detailNews.tags" :key="index">{{ tag }}</span>
              </div>
            </div>
          </div>
          <div class="modal-footer">
            <button @click="closeDetailModal">关闭</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { newsAPI } from '@/services/api';

export default {
  name: 'NewsManagement',
  data() {
    return {
      // 新闻表单数据
      newsForm: {
        title: '',
        cover_image: '',
        abstract: '',
        content: '',
        category_id: null,
        is_top: false,
        tags: []
      },
      
      // 标签输入（字符串形式）
      tagsInput: '',
      
      // 编辑中的新闻
      editingNews: {},
      
      // 新闻列表
      newsList: [],
      
      // 搜索参数
      searchParams: {
        search: '',
        category_id: null,
        is_top: '',
        skip: 0,
        limit: 10
      },
      
      // 分页信息
      currentPage: 1,
      totalItems: 0,
      jumpPage: null,
      
      // 控制模态框显示
      showModal: false,
      
      // 新闻详情模态框
      showDetailModal: false,
      detailNews: {},
      
      // 状态消息
      statusMessage: '',
      messageType: '',
      
      // 加载状态
      isLoading: false
    };
  },
  computed: {
    totalPages() {
      return Math.ceil(this.totalItems / this.searchParams.limit);
    }
  },
  mounted() {
    this.fetchNewsList();
  },
  methods: {
    // 显示状态消息
    showMessage(message, type = 'success') {
      this.statusMessage = message;
      this.messageType = type;
      
      // 5秒后自动清除消息
      setTimeout(() => {
        this.statusMessage = '';
      }, 5000);
    },
    
    // 格式化日期
    formatDate(dateString) {
      if (!dateString) return '';
      const date = new Date(dateString);
      return date.toLocaleString('zh-CN');
    },
    
    // 显示创建模态框
    showCreateModal() {
      this.resetForm();
      this.showModal = true;
      this.showDetailModal = false;
      document.body.style.overflow = 'hidden'; // 防止背景滚动
    },
    
    // 关闭模态框
    closeModal() {
      this.showModal = false;
      document.body.style.overflow = ''; // 恢复背景滚动
    },
    
    // 关闭详情模态框
    closeDetailModal() {
      this.showDetailModal = false;
      document.body.style.overflow = ''; // 恢复背景滚动
    },
    
    // 查看新闻详情
    viewNewsDetail(news) {
      this.detailNews = {...news};
      this.showDetailModal = true;
      this.showModal = false;
      document.body.style.overflow = 'hidden'; // 防止背景滚动
    },
    
    // 重置表单
    resetForm() {
      this.newsForm = {
        title: '',
        cover_image: '',
        abstract: '',
        content: '',
        category_id: null,
        is_top: false,
        tags: []
      };
      this.tagsInput = '';
      this.editingNews = {};
    },
    
    // 重置搜索
    resetSearch() {
      this.searchParams = {
        search: '',
        category_id: null,
        is_top: '',
        skip: 0,
        limit: 10
      };
      this.currentPage = 1;
      this.fetchNewsList();
    },
    
    // 搜索新闻
    searchNews() {
      this.currentPage = 1;
      this.searchParams.skip = 0;
      this.fetchNewsList();
    },
    
    // 改变页码
    changePage(page) {
      if (page < 1 || page > this.totalPages) return;
      this.currentPage = page;
      this.searchParams.skip = (page - 1) * this.searchParams.limit;
      this.fetchNewsList();
    },
    
    // 跳转到指定页码
    jumpToPage() {
      if (this.jumpPage && this.jumpPage >= 1 && this.jumpPage <= this.totalPages) {
        this.changePage(this.jumpPage);
        this.jumpPage = null;
      }
    },
    
    // 获取新闻列表
    async fetchNewsList() {
      this.isLoading = true;
      try {
        const params = {...this.searchParams};
        if (params.is_top === '') {
          delete params.is_top;
        }
        
        const response = await newsAPI.getNewsList(params);
        
        // 解析响应数据以获取总数和列表
        if (Array.isArray(response)) {
          // 如果响应是数组，总数就是数组长度
          this.newsList = response;
          this.totalItems = response.length;
        } else if (response.items) {
          // 如果响应包含items字段
          this.newsList = response.items;
          this.totalItems = response.total || response.items.length;
        } else {
          // 其他情况
          this.newsList = [];
          this.totalItems = 0;
        }
      } catch (error) {
        console.error('获取新闻列表失败:', error);
        this.showMessage('获取新闻列表失败: ' + (error.response?.data?.detail || error.message), 'error');
        this.newsList = [];
        this.totalItems = 0;
      } finally {
        this.isLoading = false;
      }
    },
    
    // 处理图片上传
    async handleImageUpload(event) {
      const file = event.target.files[0];
      if (!file) return;
      
      const formData = new FormData();
      formData.append('file', file);
      
      try {
        const response = await newsAPI.uploadImage(formData);
        
        this.newsForm.cover_image = response.url;
        this.showMessage('图片上传成功');
      } catch (error) {
        console.error('图片上传失败:', error);
        this.showMessage('图片上传失败: ' + (error.response?.data?.detail || error.message), 'error');
      }
    },
    
    // 保存新闻（创建或更新）
    async saveNews() {
      try {
        // 处理标签
        if (this.tagsInput) {
          this.newsForm.tags = this.tagsInput.split(',').map(tag => tag.trim()).filter(tag => tag);
        } else {
          this.newsForm.tags = [];
        }
        
        // 确保 category_id 是整数
        this.newsForm.category_id = parseInt(this.newsForm.category_id);
        
        let response;
        if (this.editingNews.id) {
          // 更新新闻
          // 只包含需要更新的字段，排除由后端管理的字段
          const updateData = {
            title: this.newsForm.title,
            cover_image: this.newsForm.cover_image || null,
            abstract: this.newsForm.abstract,
            content: this.newsForm.content,
            category_id: this.newsForm.category_id,
            is_top: this.newsForm.is_top,
            tags: this.newsForm.tags
          };
          
          response = await newsAPI.updateNews(this.editingNews.id, updateData);
          this.showMessage('公告更新成功');
        } else {
          // 创建新闻
          // 只发送前端需要提供的字段，完全排除后端自动生成的字段
          const createData = {
            title: this.newsForm.title,
            cover_image: this.newsForm.cover_image || null,
            abstract: this.newsForm.abstract,
            content: this.newsForm.content,
            category_id: this.newsForm.category_id,
            is_top: this.newsForm.is_top || false,
            tags: this.newsForm.tags || []
          };
          
          response = await newsAPI.createNews(createData);
          this.showMessage('公告创建成功');
        }
        
        this.closeModal();
        this.fetchNewsList();
      } catch (error) {
        console.error('保存新闻失败:', error);
        const errorMessage = error.response?.data?.detail || error.message;
        this.showMessage('保存新闻失败: ' + errorMessage, 'error');
      }
    },
    
    // 编辑新闻
    editNews(news) {
      this.editingNews = news;
      this.newsForm = {...news};
      // 处理标签显示
      this.tagsInput = Array.isArray(news.tags) ? news.tags.join(', ') : '';
      this.showModal = true;
      this.showDetailModal = false;
      document.body.style.overflow = 'hidden'; // 防止背景滚动
    },
    
    // 删除新闻
    async deleteNews(id) {
      if (!confirm('确定要删除这个公告吗？')) {
        return;
      }
      
      try {
        await newsAPI.deleteNews(id);
        this.showMessage('公告删除成功');
        this.fetchNewsList();
        
        // 如果正在编辑被删除的新闻，则关闭模态框
        if (this.editingNews.id === id) {
          this.closeModal();
        }
        
        // 如果正在查看被删除的新闻详情，则关闭详情模态框
        if (this.detailNews.id === id) {
          this.closeDetailModal();
        }
      } catch (error) {
        console.error('删除新闻失败:', error);
        this.showMessage('删除新闻失败: ' + (error.response?.data?.detail || error.message), 'error');
      }
    }
  }
};
</script>

<style scoped>
.news-management {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.card {
  background: white;
  border-radius: 10px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.08);
  padding: 25px;
  margin-bottom: 25px;
}

h1 {
  text-align: center;
  margin-bottom: 30px;
  color: #2c3e50;
  font-weight: 600;
  padding-bottom: 15px;
  border-bottom: 2px solid #3498db;
}

h2 {
  margin-bottom: 20px;
  color: #34495e;
  font-weight: 500;
  display: flex;
  align-items: center;
}

h2:before {
  content: "";
  display: inline-block;
  width: 4px;
  height: 18px;
  background: #3498db;
  margin-right: 10px;
  border-radius: 2px;
}

h3 {
  font-size: 20px;
  font-weight: 600;
  margin-bottom: 15px;
  color: #2c3e50;
}

.form-group {
  margin-bottom: 18px;
}

label {
  display: block;
  margin-bottom: 6px;
  font-weight: 500;
  color: #2c3e50;
}

input, textarea, select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 6px;
  box-sizing: border-box;
  font-size: 14px;
  transition: border-color 0.3s;
}

input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: #3498db;
  box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
}

button {
  background-color: #3498db;
  color: white;
  padding: 10px 16px;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  margin-right: 10px;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.3s;
}

button:hover {
  background-color: #2980b9;
  transform: translateY(-1px);
}

button:active {
  transform: translateY(0);
}

.btn-primary {
  background-color: #3498db;
}

.btn-danger {
  background-color: #e74c3c;
}

.btn-danger:hover {
  background-color: #c0392b;
}

.btn-warning {
  background-color: #f39c12;
  color: #fff;
}

.btn-warning:hover {
  background-color: #d35400;
}

.news-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: 20px;
  margin-top: 20px;
}

.news-item {
  border: 1px solid #eaeaea;
  border-radius: 8px;
  padding: 18px;
  background: white;
  transition: transform 0.3s, box-shadow 0.3s;
  cursor: pointer;
}

.news-item:hover {
  transform: translateY(-3px);
  box-shadow: 0 6px 15px rgba(0,0,0,0.08);
}

.news-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 12px;
  color: #2c3e50;
  display: flex;
  align-items: center;
}

.news-abstract {
  color: #7f8c8d;
  margin-bottom: 12px;
  line-height: 1.5;
}

.news-content img {
  border-radius: 6px;
  margin-bottom: 12px;
  max-width: 100%;
}

.news-meta {
  font-size: 13px;
  color: #95a5a6;
  display: flex;
  justify-content: space-between;
  margin-top: 15px;
  padding-top: 12px;
  border-top: 1px solid #f1f1f1;
}

.news-cover img {
  max-width: 100%;
  border-radius: 6px;
  margin: 10px 0;
}

.news-detail .news-content {
  margin: 15px 0;
  line-height: 1.6;
  white-space: pre-line;
}

.top-tag {
  background-color: #f39c12;
  color: white;
  padding: 3px 8px;
  border-radius: 4px;
  font-size: 12px;
  margin-right: 8px;
  font-weight: 500;
}

.search-bar {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
  flex-wrap: wrap;
  align-items: center;
}

.search-bar input, .search-bar select {
  flex: 1;
  min-width: 150px;
}

.search-bar button {
  min-width: 80px;
}

.pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 25px;
  gap: 10px;
  flex-wrap: wrap;
}

.pagination button:disabled {
  background-color: #bdc3c7;
  cursor: not-allowed;
}

.pagination button:disabled:hover {
  transform: none;
  background-color: #bdc3c7;
}

.pagination span {
  font-weight: 500;
  color: #7f8c8d;
  white-space: nowrap;
  margin: 0 5px;
}

.page-jump {
  display: flex;
  align-items: center;
  gap: 5px;
}

.page-jump input {
  width: 60px;
  padding: 5px;
}

.tag {
  display: inline-block;
  background-color: #e1f0fa;
  color: #3498db;
  padding: 3px 10px;
  border-radius: 12px;
  font-size: 12px;
  margin-right: 6px;
  margin-bottom: 6px;
  font-weight: 500;
}

/* 模态框样式 */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
  padding: 20px;
}

.modal-container {
  max-height: 90vh;
  overflow-y: auto;
  width: 100%;
  max-width: 650px;
}

.modal-content {
  background-color: #fff;
  border-radius: 10px;
  box-shadow: 0 10px 30px rgba(0,0,0,0.15);
  overflow: hidden;
}

.modal-header {
  padding: 18px 25px;
  background-color: #3498db;
  color: white;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.modal-header h2 {
  color: white;
  margin: 0;
}

.modal-header h2:before {
  background: white;
}

.close {
  color: white;
  font-size: 28px;
  font-weight: bold;
  cursor: pointer;
  line-height: 1;
}

.close:hover {
  color: #ecf0f1;
}

.modal-body {
  padding: 25px;
}

.modal-footer {
  padding: 18px 25px;
  border-top: 1px solid #eee;
  text-align: right;
  background: #f9f9f9;
}

.image-preview img {
  max-width: 100%;
  max-height: 200px;
  margin-top: 10px;
  border-radius: 4px;
}

@media (max-width: 768px) {
  .search-bar {
    flex-direction: column;
    align-items: stretch;
  }
  
  .search-bar input, .search-bar select, .search-bar button {
    min-width: auto;
    margin-bottom: 0;
  }
  
  .modal-container {
    width: 100%;
    max-height: 95vh;
  }
  
  .news-list {
    grid-template-columns: 1fr;
  }
  
  .pagination {
    flex-direction: column;
    gap: 5px;
  }
  
  .page-jump {
    margin-top: 10px;
  }
}

.status-message {
  padding: 12px;
  border-radius: 6px;
  margin: 15px 0;
  text-align: center;
  font-weight: 500;
}

.success {
  background-color: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

.error {
  background-color: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.loading {
  text-align: center;
  padding: 20px;
  color: #7f8c8d;
}
</style>